#include "vtor_i2c.h"

// 加入用户工程宏
#ifdef __DEMO_PROJECT__
#include "main.h"
#include "vtor_timer.h"
#include "vtor_printf.h"
#include "vtor_iap.h"
#include "vtor_flash_eeprom.h"


extern VtorIap vtorIap;
extern VtorFlashEeprom vtorIapEeprom;
extern VtorIapEepromData iapEepromData;

// 与at24c02保持一致吧，这个模块就相当于离线的at24c02
// 1 0 1 0 a2 a1 a0 rw，地址为0x50，写端口为0xa0，写端口为0xa1
// #define CROSS_I2C_DEV_ADDR			(0x50 << 1)
VtorI2c vtorI2cSlaveArray[4] = {
	{0x50 << 1},
	{0x51 << 1},
	{0x52 << 1},
	{0x53 << 1},
};

VtorI2c* uartI2cSlave = NULL;
VtorI2c* demoRegI2c1 = NULL;

typedef struct
{
	VtorI2c* i2c;
	GPIO_TypeDef* sclPort;
	uint16_t sclPin;
	GPIO_TypeDef* sdaPort;
	uint16_t sdaPin;
}VtorI2cSlave_Stm32HalPort;

const static VtorI2cSlave_Stm32HalPort VtorI2cSlaveGpioArray[] = 
{
	{&vtorI2cSlaveArray[0], GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7}, // demo i2c slave
	//{&vtorI2cSlaveArray[1], GPIOB, GPIO_PIN_8, GPIOB, GPIO_PIN_9}, // log i2c slave
	
	
	{NULL, 					NULL, 0, NULL, 0},
};



// 保留
void VtorI2cSlave_WriteScl(VtorI2c* i2c)
{
}

uint8_t VtorI2cSlave_ReadScl(VtorI2c* i2c)
{
	return HAL_GPIO_ReadPin(
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sclPort,
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sclPin);
}

void VtorI2cSlave_WriteSda(VtorI2c* i2c, uint8_t level)
{
	HAL_GPIO_WritePin(
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPort,
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPin,
		(GPIO_PinState)level);
}


uint8_t VtorI2cSlave_ReadSda(VtorI2c* i2c)
{
	return HAL_GPIO_ReadPin(
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPort,
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPin);
}

void VtorI2cSlave_SetSdaDir(VtorI2c* i2c, uint8_t dir)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	// 输出模式时，设置为开漏输出
	// 输入模式时，设置成边沿中断输入
	switch(dir)
	{
	case GPIO_DIR_OUTPUT:
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
		break;
	case GPIO_DIR_IT_2EDGE:
		GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
		break;
	default:
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	}
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	
	
	GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPin;
	HAL_GPIO_Init(
		VtorI2cSlaveGpioArray[i2c->i2cPortIdx].sdaPort, &GPIO_InitStruct);

}


void VtorI2cSlave_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pull = GPIO_PULLUP;
	// cubemx初始化引脚时，需配置成input，因为slaveI2c指针还未初始化
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	// 如果是在VtorI2cSlave_Init函数内，将其初始化为上升沿和下降沿中断
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

		
	// 根据不同实例进行细分配置
	for(int8_t i = 0; VtorI2cSlaveGpioArray[i].sclPort != 0; i++)
	{
		GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i].sclPin;
		HAL_GPIO_Init(VtorI2cSlaveGpioArray[i].sclPort, &GPIO_InitStruct);
		GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i].sdaPin;
		HAL_GPIO_Init(VtorI2cSlaveGpioArray[i].sdaPort, &GPIO_InitStruct);
	}
	
	
	
	// 然后 开启部中断
	HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
	
	// 最后对指针赋值，正式开启i2cSlave
	vtorI2cSlaveArray[0].i2cPortIdx = 0;
	uartI2cSlave = &vtorI2cSlaveArray[0];
}


// 触发信号后，在此函数内进行真的读取
void VtorI2cSlave_ReadBufferTask()
{
	// 将i2c收到的数据转发给uart
	uint8_t rxBuf[151] = {'\0'};
	
	if(VtorI2cSlave_ReadBuffer(uartI2cSlave, rxBuf, 151-1))
	{
		VtorDebugChanPrintf(rxBuf);
		//VtorString_ChanPrintBuffer(VTOR_PRINT_CHAN_UART1, rxBuf, rxBufLen);
	}
	VtorTimer_Stop(VtorI2cSlave_ReadBufferTask);
}

void VtorI2cSlave_StopCallback(VtorI2c* i2c)
{
	// VtorTimer_Create(VtorSlaveI2cTask, 0);
	// osMutexRelease(i2cMutex);
}

void VtorI2cSlave_WriteRegCallback(VtorI2c* i2c)
{
	
	// 主机写了接收寄存器，那么从机启动接收任务
	if(i2c->regAddr == VTOR_I2C_REG_MOSI_BUF_LEN)
	{
		VtorTimer_Create(VtorI2cSlave_ReadBufferTask, 0);
	}
	if(i2c->regAddr == VTOR_I2C_REG_MOSI_BIG_BUF)
	{
		//push i2c->serialRegister;
		// i2c->regAddr--;
	}
	//VtorPrintf("reg write [%x]=%d\r\n",
	//	i2c->regAddr, i2c->regData[i2c->regAddr]);
}

void VtorI2cSlave_ReadRegCallback(VtorI2c* i2c)
{
		
	if(i2c->regAddr == VTOR_I2C_REG_MISO_BIG_BUF_CTRL)
	{
		uint8_t misoCtrl = VtorI2cMaster_GetBigBufferMimo(
			iapEepromData.newFile.fileSize - vtorIap.iapTotalRxCnt);
		i2c->regData[i2c->regAddr] = misoCtrl;
		i2c->serialRegister = i2c->regData[i2c->regAddr];
	}
	if(i2c->regAddr == VTOR_I2C_REG_MISO_BIG_BUF)
	{
		//pop i2c->serialRegister;
		
		i2c->regData[i2c->regAddr]
			= *(uint8_t*)(vtorIap.iapStartAddr + vtorIap.iapTotalRxCnt);
		i2c->serialRegister = i2c->regData[i2c->regAddr];
		vtorIap.iapTotalRxCnt++;
		i2c->regAddr--;
	}
	
	//VtorPrintf("reg read [%x]=%d\r\n",
	//	i2c->regAddr, i2c->regData[i2c->regAddr]);
}

// 在对应的中断处理函数内，写好正确的中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	for(int8_t i = 0; VtorI2cSlaveGpioArray[i].sclPort != 0; i++)
	{
		if (GPIO_Pin == VtorI2cSlaveGpioArray[i].sclPin)
		{
			VtorI2cSlave_SclHandler(VtorI2cSlaveGpioArray[i].i2c);
			break;
		}
		if (GPIO_Pin == VtorI2cSlaveGpioArray[i].sdaPin)
		{
			VtorI2cSlave_SdaHandler(VtorI2cSlaveGpioArray[i].i2c);
			break;
		}
	}
}

void EXTI9_5_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */

  /* USER CODE END EXTI9_5_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */

  /* USER CODE END EXTI9_5_IRQn 1 */
}

#endif

